package validation

import (
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	en2 "github.com/go-playground/validator/v10/translations/en"
	zh2 "github.com/go-playground/validator/v10/translations/zh"
	"kuangstudy-mall/apis/userrelation-web/global"
	"reflect"
	"regexp"
	"strings"
)

/**
 * 官方翻译的错误信息
 * @author feige
 * @date 2024-04-17
 * @version 1.0
 * @desc
 */
func GetErrors(err error, obj any) map[string]string {
	// 反射获取结构的实例，目的就是获取属性的标签tag=msg
	s := reflect.TypeOf(obj)
	// 官方的翻译*(了解)
	m := map[string]string{}
	if filedErrors, ok := err.(validator.ValidationErrors); ok {
		for _, fieldError := range filedErrors {
			// 根据名字获取到属性对象
			field, _ := s.FieldByName(fieldError.StructField())
			msg := field.Tag.Get("msg")
			m[fieldError.Field()] = msg
		}
	}

	return m
}

/**
 * 官方翻译的错误信息
 * @author feige
 * @date 2024-04-17
 * @version 1.0
 * @desc
 */
func HandleValidatorError(err error) map[string]string {
	// 官方的翻译*(了解)
	m := map[string]string{}
	validationErrors, ok := err.(validator.ValidationErrors)
	if ok {
		translateMap := validationErrors.Translate(global.Trans)
		for key, s := range translateMap {
			skey := strings.ToLower(key[strings.Index(key, ".")+1:])
			m[skey] = s
		}
	}
	return m
}

/*
验证手机
*/
var mobile validator.Func = func(fl validator.FieldLevel) bool {
	phone := fl.Field().String()
	ok, _ := regexp.MatchString(`^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$`, phone)
	if !ok {
		return false
	}
	return true
}

/*
验证性别
*/
var gender validator.Func = func(fl validator.FieldLevel) bool {
	gender := fl.Field().String()
	ok, _ := regexp.MatchString(`^(male|woman)$`, gender)
	if !ok {
		return false
	}
	return true
}

/**
 * 初始化验证器
 * @author feige
 * @date 2024-04-17
 * @version 1.0
 * @desc
 */
func InitValidator(local string) {
	if v, flag := binding.Validator.Engine().(*validator.Validate); flag {
		// 准备翻译的语言环境----设置语言环境
		zhT := zh.New()
		enT := en.New()
		uni := ut.New(zhT, enT)
		// 通过环境获取到翻译对象
		global.Trans, _ = uni.GetTranslator("zh")
		switch local {
		case "zh":
			zh2.RegisterDefaultTranslations(v, global.Trans)
		case "en":
			en2.RegisterDefaultTranslations(v, global.Trans)
		default:
			en2.RegisterDefaultTranslations(v, global.Trans)
		}

		// 自定义验证器的注册
		v.RegisterValidation("mobile", mobile)
		v.RegisterValidation("gender", gender)

		// binding和json的绑定处理自定义信息返回
		// 注册自定义 json tag 函数
		v.RegisterTagNameFunc(func(fld reflect.StructField) string {
			name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
			if name == "-" {
				return ""
			}
			return name
		})
	}
}
